#pragma once

#include "inc.h"
#include <assert.h>
#include <boost/noncopyable.hpp>
#include <util/filepath.h>

namespace GLC {

/**
 * @brief The Texture2D class - managed reference to real texture object,
 * ctor increases references count to real texture, dtor decreases.
 * Manager will destroy real texture object when reference count become 0.
 */
class Texture2D : public boost::noncopyable
{
public:
    Texture2D(const std::string &name);
    ~Texture2D();

    void bind() const;
    static void unbind();

    const std::string &name() const;

    uintptr_t getHandle() const;

private:
    friend class Texture2DRef;

    std::string _name;
    uintptr_t _texture;
};

/**
 * @brief The Texture2DRef class - fast, but not managed reference to texture
 */
class Texture2DRef
{
public:
    /**
     * @brief createNull - creates moc texture, binding it equal to Texture2D::unbind()
     * @return
     */
    static Texture2DRef createNull();

    /**
     * @brief Texture2DRef - create reference to given texture
     * @param source
     */
    Texture2DRef(const Texture2D &source);

    /**
     * @brief bind - applies texture to next primitives/models, until next bind/unbind called
     */
    void bind() const;

    static void unbind();
    bool isNull() const;

    uintptr_t getHandle() const;

private:
    Texture2DRef();
    uintptr_t _texture;
};

} // namespace GLC
